﻿using LitJson;
using System.Collections.Generic;
using System.IO;

namespace Devil.Persistent
{
    using Handler = ParallelDispatcher.Handler;

    /// <summary>
    /// 共享序列化对象
    /// </summary>
    public interface ISharedInstance
    {
        int InstanceId { get; }
    }

    /// <summary>
    /// 引用实例
    /// </summary>
    public interface IReferencedPersistent
    {
        void GetReferencedInstances(ICollection<ISharedInstance> objs);
    }

    /// <summary>
    /// 存储类型
    /// </summary>
    public enum EPersistentType
    {
        System, // 系统数据（默认）
        GamePlay, // 游戏数据
    }

    /// <summary>
    /// 存储文件元数据
    /// </summary>
    public interface IPersistentMeta
    {
        EPersistentType BlockType { get; }
        void OnWillSaveFile(string filePath);
    }

    /// <summary>
    /// Json 数据序列化
    /// </summary>
    public  interface IJsonSerializable
    {
        JsonData OnSerialize();
        void OnDeserialize(JsonData content);
    }

    /// <summary>
    /// 持久化系统模块
    /// </summary>
    public interface IPersistentModule { }

    public interface IBeforeSerializeScheduler : IPersistentModule
    {
        Handler Schedule(IPersistentMeta meta);
    }

    //public interface IAfterSerializeScheduler : IPersistentModule
    //{
    //    Handler Schedule(IPersistentMeta meta);
    //}

    public interface IBeforeDeserializeScheduler : IPersistentModule
    {
        Handler Schedule(IPersistentMeta meta);
    }

    //public interface IAfterDeserializeScheduler : IPersistentModule
    //{
    //    Handler Schedule(IPersistentMeta meta);
    //}

    /// <summary>
    /// 序列化系统
    /// </summary>
    public interface IPersistentBlock : IPersistentModule
    {
        int Version { get; }

        string BlockName { get; }

        EPersistentType BlockType { get; }

        /// <summary>
        /// 是否可作为实例存储组件
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        bool IsInstanceSerializer(object instance);

        /// <summary>
        /// 创建实例
        /// </summary>
        /// <param name="version"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        object CreateInstance(JsonData content);
        
        /// <summary>
        /// 序列化实例
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        JsonData OnSerializeParallel(object instance);

        /// <summary>
        /// 反序列化实例
        /// </summary>
        /// <param name="version"></param>
        /// <param name="instance"></param>
        /// <param name="content"></param>
        void OnDeserializeParallel(object instance, JsonData content);

        /// <summary>
        /// 收集可序列化实例
        /// </summary>
        /// <param name="datas"></param>
        void GatherPersistentDatas(ICollection<object> datas);

    }

    /// <summary>
    /// 持久化数据版本更新
    /// </summary>
    public interface IUpgradablePersistentBlock : IPersistentBlock
    {
        JsonData Upgrade(JsonData content);
    }

    /// <summary>
    /// 当 IPersistentBlock 对象实现该接口， 在反序列化完成时调用 RestorePersistentDatas
    /// </summary>
    public interface IRestorablePersistentBlock : IPersistentBlock
    {

        /// <summary>
        /// 恢复已经序列化对象
        /// </summary>
        /// <param name="datas"></param>
        /// <param name="referenced"></param>
        void RestorePersistentDatas(ICollection<object> datas, ICollection<object> referenced);

    }

    /// <summary>
    /// 二进制文件持久化
    /// </summary>
    public interface IBinaryPersistentFile : ISharedInstance
    {
        string FileType { get; }
        int GetBytes(ref byte[] buffer);
        void LoadBytes(byte[] buffer, int offset, int length);
    }

}
